home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
wb
/
czesc_4
/
tapete
/
tapete.mod
< prev
next >
Wrap
Text File
|
1992-03-02
|
12KB
|
473 lines
(*
* :Program. Tapete.mod
* :Author. Fridtjof Siebert
* :Address. Nobileweg 67, D-7000 Stuttgart 40
* :Shortcut. [fbs]
* :Copyright. FreeWare
* :Language. Oberon-2
* :Translator. Amiga Oberon Compiler V2.30 (inoffical version)
* :History. V1.0 02-Mar-92: first published version [fbs]
* :Contents. Tool to replace WBPattern by an arbitrary image
* :Usage. Tapete <picture> [SAMECOLORS]
* :Remark. Compile: 'Oberon -m Tapete', don't use small data model!
* :Remark. Link: 'OLink -s Tapate OBJ LoadBody.o'
*
*
*
* Bitte nur mit großem Datenmodell:
*
* $IFNOT SmallData
*
*)
MODULE Tapete;
IMPORT Exec,
Graphics,
SYSTEM,
Dos,
OberonLib,
Strings,
IFFSupport,
Arguments;
(*-------------------------------------------------------------------------*)
TYPE
BP = PROCEDURE (rp{9} : Graphics.RastPortPtr;
mask{8} : Graphics.PLANEPTR;
xMin{0} : INTEGER;
yMin{1} : INTEGER;
xMax{2} : INTEGER;
yMax{3} : INTEGER;
bytecnt{4} : INTEGER);
(*
* Typ der BltPattern()-Prozedur
*)
VAR
OldBP: BP;
(*
* Original BltPattern-Prozedur.
*)
(*-------------------------------------------------------------------------*)
TYPE
PatPlane = ARRAY 16 OF INTEGER;
PatPlanePtr = UNTRACED POINTER TO PatPlane;
(*
* Typen für WB-AreaPattern
*)
OldPat = STRUCT
weissnich: ARRAY 9 OF INTEGER;
pad: SHORTINT;
depth: SHORTINT;
data: ARRAY 8 OF PatPlane; (* eigentlich: ARRAY depth OF PatPlane *)
END;
(*
* Inhalt von ENV:sys/wb.pat
*)
CONST
IdentifyPattern =
PatPlane(0162FU,0F5A2U,0A18AU,00D66U,0FD1AU,07F9CU,0E15AU,05265U,
0C5C9U,06460U,0494FU,0E5DBU,0BC61U,0FF7BU,01510U,09432U);
(*
* Durch Zufallszahlen erzeugtes Muster. Dieses wird verwendet, um die
* BltPattern-Aufrufe der Workbench zu identifizieren. Immer, wenn ein mit
* Rechteck diesem Muster gefüllt wird, wird stattdessen das Bild gezeichnet.
*)
(*-------------------------------------------------------------------------*)
VAR
f: Dos.FileHandlePtr; (* Generelles FileHandle zum Laden und Speichern. *)
oldwbpat, wbpat: OldPat; (* Altes und neues ENV:sys/wb.pat *)
restoreWBPat: BOOLEAN; (* Muß bei CLOSE ENV:sys/wb.pat neu geschrieben werden? *)
WBPatSize: LONGINT; (* Größe von oldwbpat *)
size: LONGINT; (* verschieden verendet, größe von Dateien *)
s,w: SYSTEM.ADDRESS; (* Dummys für IFFSupport.ReadILBM() *)
Image: Graphics.BitMapPtr; (* Geladenes Bild *)
i: INTEGER; (* Durchwandern der Argumente, Farben und Planes *)
arg,Pic: ARRAY 256 OF CHAR;(* Akutuelles Argument, Name des Bildes *)
SameColors: BOOLEAN; (* ist SAMECOLORS angegeben? *)
color: ARRAY 3 OF BYTE; (* Zum Speichern der Farben *)
ColorSize: LONGINT; (* Zum Speichern von ENV:sys/palette.ilbm *)
CMAPSize: LONGINT; (* dito *)
OldPalette: ARRAY 512 OF CHAR; (* Vorheriger Inhalt von ENV:sys/palette.ilbm *)
restorePalette: BOOLEAN; (* Muß bei CLOSE ENV:sys/palette.ilbm neu geschrieben werden? *)
PaletteSize: LONGINT; (* Gröe von OldPalette *)
port: Exec.MsgPortPtr; (* MessagePort, zum Prüfen, ob Tapete schon gestartet wurde *)
(*-------------------------------------------------------------------------*)
PROCEDURE FillWithImage(rp:Graphics.RastPortPtr; x,y,X,Y: INTEGER); (* $Debug- $StackChk- *)
(*
* Zeichnet Image in rp in das Rechteck (x,y),(X,Y).
*
* Ist der Bereich größer als das Bild selbst, wird das Bild stückchenweise
* gezeichnet.
*
*)
VAR
width,height,w,h,startx,starty,Imagex,Imagey: INTEGER;
BEGIN
height := Y-y+1;
starty := y;
Imagey := starty MOD IFFSupport.NuScreen.height;
WHILE height>0 DO
h := IFFSupport.NuScreen.height - Imagey;
IF h>height THEN h := height END;
width := X-x+1;
startx := x;
Imagex := startx MOD IFFSupport.NuScreen.width;
WHILE width>0 DO
w := IFFSupport.NuScreen.width - Imagex;
IF w>width THEN w := width END;
Graphics.BltBitMapRastPort(Image,Imagex,Imagey,rp,startx,starty,w,h,0C0X);
DEC(width,w);
INC(startx,w);
Imagex := 0;
END;
DEC(height,h);
INC(starty,h);
Imagey := 0;
END;
END FillWithImage;
PROCEDURE CheckPtrn(p: PatPlanePtr): BOOLEAN; (* $StackChk- *)
(*
* Prüft, ob p#NIL und p^ gleich dem IdentifyPattern ist.
* Dabei wird auch berücksichtigt, daß p^ evtl. vertikal
* verschoben wurde.
*)
VAR
y,i: INTEGER;
BEGIN
IF p#NIL THEN
y := 0;
WHILE (y<16) & (p[0]#IdentifyPattern[y]) DO INC(y) END;
IF y<16 THEN
i := 0;
WHILE IdentifyPattern[y]=p[i] DO
INC(i);
y := (y+1) MOD 16;
IF i=16 THEN RETURN TRUE END;
END;
END;
END;
RETURN FALSE;
END CheckPtrn;
PROCEDURE NewBltPattern (rp{9} : Graphics.RastPortPtr; (* $SaveRegs+ $StackChk- *)
mask{8} : Graphics.PLANEPTR;
xMin{0} : INTEGER;
yMin{1} : INTEGER;
xMax{2} : INTEGER;
yMax{3} : INTEGER;
bytecnt{4} : INTEGER);
(*
* Neue, mit SetFunction aktivierte BltPattern()-Routine.
*)
VAR
xm,ym: INTEGER;
BEGIN
xm := xMin; ym := yMin;
IF CheckPtrn(rp.areaPtrn) THEN
FillWithImage(rp,xm,ym,xMax,yMax);
ELSE
OldBP(rp,mask,xm,ym,xMax,yMax,bytecnt);
END
END NewBltPattern; (* $StackChk+ $Debug= *)
(*-------------------------------------------------------------------------*)
BEGIN
(*
* 2.0 only:
*)
IF Dos.dos.lib.version<37 THEN HALT(20) END;
(*
* zunächst wird geprüft, ob wir schon einmal gestartet wurden:
*)
Exec.Forbid;
port := Exec.FindPort("Tapeziertisch");
IF port#NIL THEN
Exec.Signal(port.sigTask,LONGSET{Dos.ctrlC});
port := NIL;
Exec.Permit;
Dos.PrintF("Signalled Tapete to quit.\n");
HALT(0);
ELSE
INCL(OberonLib.MemReqs,Exec.public);
NEW(port);
EXCL(OberonLib.MemReqs,Exec.public);
IF port=NIL THEN
Exec.Permit;
Dos.PrintF("Out of memory!\n");
HALT(20);
END;
port.node.name := SYSTEM.ADR("Tapeziertisch");
port.node.type := Exec.msgPort;
port.flags := Exec.signal;
port.sigTask := Exec.exec.thisTask;
Exec.AddPort(port)
END;
Exec.Permit;
(*
* Nun werden die Argumente ausgewertet:
*)
FOR i:=1 TO Arguments.NumArgs() DO
Arguments.GetArg(i,arg);
Strings.Upper(arg);
IF arg="SAMECOLORS" THEN
SameColors := TRUE
ELSE
Arguments.GetArg(i,Pic);
END;
END;
IF (Pic="") OR (Pic="?") THEN
Dos.PrintF("Usage: Tapete <Picture> [SAMECOLORS]\n");
HALT(5);
END;
(*
* Das Bild wird geladen:
*)
IF ~ IFFSupport.ReadILBM(Pic,{IFFSupport.usebmsize,IFFSupport.dontopen,IFFSupport.visible},s,w) THEN
Dos.PrintF("Couldn't load %s!\n",SYSTEM.ADR(Pic));
HALT(20);
END;
Image := IFFSupport.NuScreen.customBitMap;
(*
* Neue Palette setzen:
*)
IF ~ SameColors THEN
f := Dos.Open("ENV:sys/palette.ilbm",Dos.oldFile);
IF f=NIL THEN Dos.PrintF("ENV:sys/palette.ilbm not found!\n"); HALT(20) END;
PaletteSize := Dos.Read(f,OldPalette,SIZE(OldPalette));
IF ~ Dos.Close(f) OR (PaletteSize<=0) THEN
Dos.PrintF("Error Reading ENV:sys/palette.ilbm!\n");
HALT(20);
END;
restorePalette := TRUE;
f := Dos.Open("ENV:sys/palette.ilbm",Dos.newFile);
IF f=NIL THEN Dos.PrintF("Couldn't open ENV:sys/palete.ilbm!\n"); HALT(20) END;
CMAPSize := 3*IFFSupport.IFFInfo.CMAP.colorCnt;
IF ODD(CMAPSize) THEN INC(CMAPSize) END;
ColorSize := CMAPSize + 56;
size := Dos.Write(f,"FORM" ,4) +
Dos.Write(f,ColorSize,4) +
Dos.Write(f,"ILBMBMHD"
"\x00\x00\x00\x14\x00\x10\x00\x01\x00\x00\x00\x00\x04\x00\x00\x00"
"\x00\x00\x0A\x0B\x01\x40\x00\xC8CMAP",36) +
Dos.Write(f,CMAPSize,4);
FOR i := 0 TO IFFSupport.IFFInfo.CMAP.colorCnt - 1 DO
color[0] := CHR(LONG(IFFSupport.IFFInfo.CMAP.red [i])*16);
color[1] := CHR(LONG(IFFSupport.IFFInfo.CMAP.green[i])*16);
color[2] := CHR(LONG(IFFSupport.IFFInfo.CMAP.blue [i])*16);
INC(size,Dos.Write(f,color,3));
END;
IF ODD(IFFSupport.IFFInfo.CMAP.colorCnt) THEN
INC(size,Dos.Write(f,"\x00",1));
END;
INC(size,Dos.Write(f,"BODY\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00",16));
IF ~ Dos.Close(f) OR (size#ColorSize+8) THEN
Dos.PrintF("Error writing ENV:sys/palette.ilbm!\n");
HALT(20);
END;
END;
(*
* Neue BltPattern()-Routine aktivieren:
*)
OldBP := SYSTEM.VAL(BP,Exec.SetFunction(Graphics.gfx,-312,SYSTEM.VAL(Exec.PROC,NewBltPattern)));
(*
* Altes ENV:sys/wb.pat laden:
*)
f := Dos.Open("ENV:sys/wb.pat",Dos.oldFile);
IF f=NIL THEN Dos.PrintF("ENV:sys/wb.pat not found!\n"); HALT(20) END;
WBPatSize := Dos.Read(f,wbpat,SIZE(wbpat));
IF ~ Dos.Close(f) OR (WBPatSize<52) THEN
Dos.PrintF("Error Reading ENV:sys/wb.pat!\n");
HALT(20);
END;
oldwbpat := wbpat;
(*
* Neues ENV:sys/wb.pat speichern:
*)
wbpat.data[0] := IdentifyPattern;
restoreWBPat := TRUE;
f := Dos.Open("ENV:sys/wb.pat",Dos.newFile);
IF f=NIL THEN Dos.PrintF("Couldn't open ENV:sys/wb.pat!\n"); HALT(20) END;
size := WBPatSize - Dos.Write(f,wbpat,WBPatSize);
IF ~ Dos.Close(f) OR (size#0) THEN
Dos.PrintF("Error writing ENV:sys/wb.pat!\n");
HALT(20);
END;
(*
* Warten, bis man uns nicht mehr will:
*)
REPEAT UNTIL Dos.ctrlC IN Exec.Wait(LONGSET{Dos.ctrlC});
CLOSE
(*
* ENV:sys/palette.ilbm zurückschreiben:
*)
IF restoreWBPat THEN
f := Dos.Open("ENV:sys/wb.pat",Dos.newFile);
IF f=NIL THEN
Dos.PrintF("Couldn't open ENV:sys/wb.pat!\n")
ELSE
DEC(WBPatSize,Dos.Write(f,oldwbpat,WBPatSize));
IF ~ Dos.Close(f) OR (WBPatSize#0) THEN
Dos.PrintF("Error writing ENV:sys/wb.pat!\n");
END;
END;
END;
(*
* ENV:sys/wb.pat zurückschreiben:
*)
IF restorePalette THEN
f := Dos.Open("ENV:sys/palette.ilbm",Dos.newFile);
IF f=NIL THEN
Dos.PrintF("Couldn't open ENV:sys/palete.ilbm!\n")
ELSE
DEC(PaletteSize,Dos.Write(f,OldPalette,PaletteSize));
IF ~ Dos.Close(f) OR (PaletteSize#0) THEN
Dos.PrintF("Error writing ENV:sys/palette.ilbm!\n");
END;
END;
END;
(*
* BltPattern wieder auf alte Routine setzen.
*
* ACHTUNG: Hier wird nicht geprüft, ob ein anderes Programm unterdessen
* BltPattern mit SetFunction() verändert hat. Ist dies der Fall, stürzt
* die Maschine ab.
*)
IF OldBP # NIL THEN
IF Exec.SetFunction(Graphics.gfx,-312,SYSTEM.VAL(Exec.PROC,OldBP))=NIL THEN END;
END;
(*
* Speicher für Bild freigeben:
*)
IF Image#NIL THEN
FOR i:=0 TO Image.depth-1 DO
Graphics.FreeRaster(Image.planes[i],IFFSupport.NuScreen.width,IFFSupport.NuScreen.height);
END;
DISPOSE(Image);
END;
(*
* Port schließen:
*)
IF port#NIL THEN Exec.RemPort(port) END;
END Tapete.
(* $END *)